/*!
  @file data_handler.h
  @brief Brief Description
  @author Kyohei Otsu <kyon@ac.jaxa.jp>
  @date April, 2013
*/

#ifndef _DATA_HANDLER_H_
#define _DATA_HANDLER_H_

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

#include <tr1/memory>

#include "core/core.h"

namespace net
{

//! Data handler base class
/*! implemening data send and recv functions */
class DataHandler {
 public:

  typedef std::tr1::shared_ptr<DataHandler> Ptr;

  //! Constructor
  DataHandler() : CHUNK_SIZE(64), connected_(false) { }
  DataHandler(const int sock, const char *mode) : CHUNK_SIZE(64), connected_(false) { init(sock, mode); }

  //! Destructor
  virtual ~DataHandler()
  { 
    INFO("free buffer");
    free(buf_);
  }


  //! initialization of file pointer
  //! @param mode See fopen(3)
  void init(const int sock, const char *mode);

  //! start threads
  void startThreads();

  //! stop threads
  void killThreads();

  //! receive data
  static void* receiveData(void *_arg);

  //! send data
  static void* sendData(void *_arg);

  
  int sock() const { return sock_; }
  void set_sock(int sock) { sock_ = sock; }

  FILE *fp() const { return fp_; }
  void set_fp(FILE* fp) { fp_ = fp; }

 protected:

  //! size of buffer
  size_t CHUNK_SIZE;

  virtual int onReceive() = 0;
  virtual int onSend() = 0;

  //! true if connected 
  bool connected_;

  //! socket
  int sock_;

  //! file pointer
  FILE* fp_;
  
  //! data temporary buffer
  unsigned char *buf_;

  pthread_t sthread_, rthread_;

};

} // end of namespace

#endif
